package MawsonClient.GUI;

import MawsonClient.Config;
import MawsonClient.LogHandler;
import MawsonClient.Mawson;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.text.html.HTMLDocument;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

/**
 * User: Ryan Green
 * Date: Nov 5, 2010
 * Time: 3:54:24 PM
 * Copyright - University of South Australia
 */
public class MawsonFrame extends JFrame {

	ArrayList<RequestedDataElement> perFileElements;
	ArrayList<ArrayList<RequestedDataElement>> perLineElements;
	ArrayList<ArrayList<RequestedDataElement>> perAggElements;
	HashMap<Integer, String> aggMap;
	HashSet<String> skipList;
	Config config;
	LogHandler log;

	ButtonPanel buttonPanel;
	PerFilePanel perFilePanel;
	PerLinePanel perLinePanel;
	PerAggPanel perAggPanel;

	Mawson parent;

	public MawsonFrame(Mawson parent,
	            String filename,
	            ArrayList<RequestedDataElement> perFileElements,
	            ArrayList<ArrayList<RequestedDataElement>> perLineElements,
	            ArrayList<ArrayList<RequestedDataElement>> perAggElements,
	            HashMap<Integer, String> aggMap,
	            Config config,
	            LogHandler log) {

		super("MawsonClient.Mawson 2011");

		this.parent = parent;
		this.perLineElements = perLineElements;
		this.perFileElements = perFileElements;
		this.perAggElements = perAggElements;
		this.aggMap = aggMap;
		this.config = config;
		this.log = log;

		skipList = new HashSet<String>();

		Border titled = BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "");

		this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				if (JOptionPane.showConfirmDialog(null, "Are you sure you want to end this session?", "Confirm", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
					closeWindow();
				//finished();
			}
		});
		// This is an empty content area in the frame
		Toolkit tk = Toolkit.getDefaultToolkit();
		Dimension screenSize = tk.getScreenSize();
		this.setLocation((screenSize.width / 2) - 150, (screenSize.height / 2) - 150);
		this.setMinimumSize(new Dimension(300, 300));

		//the header panel
		JPanel headerPanel = new JPanel(new BorderLayout());
		headerPanel.setBorder(titled);
		JLabel headerLabel = new JLabel(filename);
		headerLabel.setHorizontalAlignment(JLabel.CENTER);
		headerPanel.add(headerLabel, BorderLayout.CENTER);

		//the centre panel
		JPanel greaterCentrePanel = new JPanel(new BorderLayout());
		perFilePanel = new PerFilePanel(this);
		greaterCentrePanel.add(perFilePanel, BorderLayout.NORTH);
		perLinePanel = new PerLinePanel(this);
		greaterCentrePanel.add(perLinePanel, BorderLayout.SOUTH);
		perAggPanel = new PerAggPanel(this);
		greaterCentrePanel.add(perAggPanel, BorderLayout.CENTER);

		buttonPanel = new ButtonPanel(this);

		if (perAggElements.size() > perLineElements.size()) buttonPanel.pages = perAggElements.size();
		else if (perLineElements.size() > perAggElements.size()) buttonPanel.pages = perLineElements.size();
		else buttonPanel.pages = 1;


		this.getContentPane().add(greaterCentrePanel, BorderLayout.CENTER);
		this.getContentPane().add(headerPanel, BorderLayout.NORTH);
		this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);

		//display the right agg card
		if (perAggElements.size() > 0) {
			CardLayout cl2 = (CardLayout) (perAggPanel.getLayout());
			cl2.show(perAggPanel, aggMap.get(buttonPanel.count - 1));
		}

		buttonPanel.update();
		this.pack();
		this.setVisible(true);
	}

	private void closeWindow() {
		this.dispose();
	}

	public void finished() {
		this.setVisible(false);

		//the perAgg elements - update the parent.inputFile
		//for each line in the input file
		for (ArrayList<RequestedDataElement> list : perAggElements) {
			for (int i = 0; i < parent.inputFile.size(); i++) {
				int tmpCount = config.numCompleteColumns;
				for (RequestedDataElement element : list) {
					tmpCount++;
					String val = parent.inputFile.get(i).get(element.aggIndex);
					if (val.equals(element.getVal())) {
						String output = "";
						if (element.comp instanceof JTextField) {
							JTextField text = (JTextField) element.comp;
							output = text.getText();
						} else if (element.comp instanceof JComboBox) {
							JComboBox box = (JComboBox) element.comp;
							output = (String) box.getSelectedItem();
						} else {
							log.LogAndExit("Error: data.comp is not of known swing component type.", true);
						}

						parent.inputFile.get(i).put(tmpCount, output);
					}
				}
			}
		}

		if (perAggElements.size() > 0) config.numCompleteColumns += perAggElements.get(0).size();

		for (RequestedDataElement data : perFileElements) {
			config.numCompleteColumns++;
			for (int i = 0; i < parent.inputFile.size(); i++) {
				String output = "";
				if (data.comp instanceof JTextField) {
					JTextField text = (JTextField) data.comp;
					output = text.getText();
				} else if (data.comp instanceof JComboBox) {
					JComboBox box = (JComboBox) data.comp;
					output = (String) box.getSelectedItem();
				} else {
					log.LogAndExit("Error: data.comp is not of known swing component type.", true);
				}

				parent.inputFile.get(i).put(config.numCompleteColumns, output);
			}
		}

		for (int i = 0; i < perLineElements.size(); i++) {
			config.numCompleteColumns++;
			for (RequestedDataElement data : perLineElements.get(i)) {
				String output = "";
				if (data.comp instanceof JTextField) {
					JTextField text = (JTextField) data.comp;
					output = text.getText();
				} else if (data.comp instanceof JComboBox) {
					JComboBox box = (JComboBox) data.comp;
					output = (String) box.getSelectedItem();
				} else {
					log.LogAndExit("Error: data.comp is not of known swing component type.", true);
				}
				parent.inputFile.get(i).put(config.numCompleteColumns, output);
			}
		}

		//delete the skipped lines by creating a new variable and copying only the non-skipped lines
		ArrayList<HashMap<Integer, String>> tmpInputFile = new ArrayList<HashMap<Integer, String>>();
		for (int i = 0 ; i < parent.inputFile.size(); i++){
			if (!skipList.contains(aggMap.get(i))) tmpInputFile.add(parent.inputFile.get(i));
		}
		parent.inputFile = tmpInputFile;

		parent.outputData();

		this.dispose();
	}

	public boolean askUserPass() {
		JPanel panel = new JPanel();

		panel.setLayout(new GridLayout(4, 1));

		JLabel username = new JLabel("Username");
		JLabel password = new JLabel("Password");

		JTextField textField = new JTextField(20);
		JPasswordField passwordField = new JPasswordField(20);

		panel.add(username);
		panel.add(textField);
		panel.add(password);
		panel.add(passwordField);

		if (JOptionPane.showConfirmDialog(null,panel,"Please enter your username and password",JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION){
			config.username = textField.getText();
			config.password = new String(passwordField.getPassword());
			return true;
		}

		return false;
	}
}
